import { defineComponent, reactive, ref, Ref } from 'vue';
import { IAppThemeService, IParam } from 'ibz-core';
import { App } from '../../core';
import './app-theme.scss';
const AppThemeProps = {};

export const AppThemeComponent = defineComponent({
  name: 'AppTheme',
  props: AppThemeProps,
  setup(props: any) {
    /**
     * @description 应用
     * @type {App}
     */
    const application = App.getInstance();

    /**
     * @description 应用主题服务
     * @type {AppThemeService}
     */
    const appThemeService: IAppThemeService = application.getAppThemeService();

    /**
     * @description 应用内置主题
     * @type {IParam[]}
     */
    const presetTheme: IParam[] = appThemeService.getPresetTheme();

    /**
     * @description 当前激活主题
     * @type {*}
     */
    let activeTheme: any = reactive({
      isCustom: false,
      theme: 'default',
    });

    /**
     * @description 是否显示自定义面板
     * @type {Ref<boolean>}}
     */
    const showCustomPanel: Ref<boolean> = ref(false);

    /**
     * @description
     * @type {Ref<boolean>}}
     */
    let themeOptions: any = reactive([]);

    return {
      appThemeService,
      presetTheme,
      activeTheme,
      showCustomPanel,
      themeOptions,
    };
  },
  mounted() {
    this.initAppTheme();
  },
  methods: {
    /**
     * @description 初始化应用主题
     */
    initAppTheme() {
      const initOptions = this.appThemeService.initAppTheme();
      this.activeTheme.isCustom = initOptions.activeTheme.isCustom;
      this.activeTheme.theme = initOptions.activeTheme.theme;
      this.themeOptions.splice(0, this.themeOptions.length);
      (initOptions.themeOptions || []).forEach((option: IParam) => {
        this.themeOptions.push(option);
      });
    },

    /**
     * @description 切换主题
     * @param {IParam} item 主题
     * @param {*} event 源事件对象
     * @return {*}
     */
    changeInternalTheme(item: IParam, event: any) {
      this.showCustomPanel = false;
      if (this.activeTheme.theme === item.name && !this.activeTheme.isCustom) {
        return;
      }
      this.appThemeService.changeInternalTheme(this.activeTheme.theme, item.name, this.themeOptions);
      this.activeTheme.theme = item.name;
      this.activeTheme.isCustom = false;
    },

    /**
     * @description 重置主题
     */
    resetAppTheme() {
      this.appThemeService.resetAppTheme(this.themeOptions);
    },

    /**
     * @description 处理自定义
     * @param {*} event
     */
    handleCustom(event: any) {
      this.showCustomPanel = !this.showCustomPanel;
      if (this.showCustomPanel) {
        if (!this.activeTheme.isCustom) {
          this.resetAppTheme();
        }
        this.initAppTheme();
      }
    },
    /**
     * @description 混合颜色（混合失败返回颜色1）
     * @param {string} color1 颜色1
     * @param {string} color2 颜色2
     * @param {number} [weight=0.5] 颜色1占比
     * @return {*} 
     */
    mixColor(color1: string, color2: string, weight: number = 0.5) {
      if (weight > 1 || weight < 0) {
        weight = 0.5;
      }
      const res = /#[0-9a-fA-F]{6}/;
      if (color1 && res.test(color1) && color2 && res.test(color2)) {
        const d2h = (d: any) => {
          return d.toString(16);
        }
        const h2d = (h: any) => {
          return parseInt(h, 16);
        }
        let color = "#";
        for (let i = 0; i <= 5; i += 2) {
          const c1 = h2d(color1.substr(i + 1, 2));
          const c2 = h2d(color2.substr(i + 1, 2));
          const val = d2h(Math.ceil(c2 + (c1 - c2) * weight));
          color += (val.length == 1 ? `0${val}` : val);
        }
        return color;
      }
      return color1;
    },
    /**
     * @description 获取阴影色
     * @param {string} color 主基调颜色
     * @return {string} 
     */
    getColorShade(color: string): string {
      return this.mixColor(color, '#000000', 0.88);
    },
    /**
     * @description 获取浅色
     * @param {string} color 主基调颜色
     * @return {*}  {string}
     */
    getColorTint(color: string): string {
      return this.mixColor(color, '#FFFFFF', 0.9);
    },
    /**
     * @description 颜色选择变化
     * @param {IParam} item
     * @param {*} event
     */
    colorPickerChange(item: IParam, event: any) {
      item.isChange = true;
      const doc = document.documentElement;
      doc.style.setProperty(item.key, item.default);
      if (item.shade) {
        const shade = this.getColorShade(item.default);
        item.shade = shade;
        doc.style.setProperty(`${item.key}-shade`, shade);
      }
      if (item.tint) {
        const tint = this.getColorTint(item.default);
        item.tint = tint;
        doc.style.setProperty(`${item.key}-tint`, tint);
      }
    },

    /**
     * @description 应用自定义主题
     * @param {*} event
     */
    applyCustomTheme(event: any) {
      this.activeTheme.isCustom = true;
      this.appThemeService.applyCustomTheme(this.activeTheme.theme, this.themeOptions);
    },

    /**
     * @description 渲染颜色选择
     * @param {IParam} item 配置项
     * @return {*}
     */
    renderColorPicker(item: IParam) {
      return (
        <div
          class='theme-option__input'
          onClick={(event: any) => {
            event.stopPropagation();
          }}
        >
          <div class='theme-option__color-picker' style={{ backgroundColor: item.default }}>
            <input
              type='color'
              v-model={item.default}
              onChange={(event: any) => {
                this.colorPickerChange(item, event);
              }}
            />
          </div>
          <input
            type='text'
            v-model={item.default}
            onChange={(event: any) => {
              this.colorPickerChange(item, event);
            }}
          />
        </div>
      );
    },

    /**
     * @description
     * @param {IParam} item
     * @return {*}
     */
    renderOptionItemForColor(item: IParam) {
      return [
        <ion-item
          class='theme-option theme-option__basic'
          onClick={() => {
            item.showChild = !item.showChild;
          }}
        >
          <ion-label class='theme-option__color-name'>
            <div class='theme-option__color-preview' style={{ backgroundColor: item.default }}></div>
            <span>{(this as any).$tl(item.lanResTag, item.title)}</span>
          </ion-label>
          <div class='theme-option__color-group'>
            {this.renderColorPicker(item)}
            <app-icon name={item.showChild ? 'chevron-up-outline' : 'chevron-down-outline'}></app-icon>
          </div>
        </ion-item>,
        item.showChild
          ? [
            <ion-item class='theme-option theme-option__shade'>
              <ion-label class='theme-option__color-name'>
                <div class='theme-option__color-preview' style={{ backgroundColor: item.shade }}></div>
                <span>{`${(this as any).$tl(item.lanResTag, item.name)}（${(this as any).$tl(
                  'theme.shadow',
                  '阴影',
                )}）`}</span>
              </ion-label>
              <div class='theme-option__color-hex'>
                <div style={{ color: item.shade }}>{item.shade}</div>
              </div>
            </ion-item>,
            <ion-item class='theme-option theme-option__tint'>
              <ion-label class='theme-option__color-name'>
                <div class='theme-option__color-preview' style={{ backgroundColor: item.tint }}></div>
                <span>{`${(this as any).$tl(item.lanResTag, item.title)}（${(this as any).$tl(
                  'theme.tint',
                  '浅色',
                )}）`}</span>
              </ion-label>
              <div class='theme-option__color-hex'>
                <div style={{ color: item.tint }}>{item.tint}</div>
              </div>
            </ion-item>,
          ]
          : null,
      ];
    },

    /**
     * @description 渲染配置项
     * @param {IParam} item
     * @return {*}
     */
    renderOptionItem(item: IParam) {
      return (
        <ion-item class='theme-option theme-option__default'>
          <ion-label class='theme-option__color-name'>
            <div class='theme-option__color-preview' style={{ backgroundColor: item.default }}></div>
            <span>{(this as any).$tl(item.lanResTag, item.title)}</span>
          </ion-label>
          <div class='theme-option__color-group'>{this.renderColorPicker(item)}</div>
        </ion-item>
      );
    },

    /**
     * @description 渲染分组
     * @param {IParam} options
     * @return {*}
     */
    renderGroups(options: IParam) {
      return [
        <ion-item-divider>
          <ion-label>{(this as any).$tl(options.lanResTag, options.title)}</ion-label>
        </ion-item-divider>,
        options.items && options.items.length > 0
          ? options.items.map((item: IParam) => {
            if (options.name == 'color') {
              return this.renderOptionItemForColor(item);
            } else {
              return this.renderOptionItem(item);
            }
          })
          : null,
      ];
    },

    /**
     * @description 渲染内容区
     * @return {*}
     */
    renderContent() {
      return [
        this.presetTheme.map((item: IParam) => {
          const isUse = this.activeTheme.theme === item.name && !this.activeTheme.isCustom;
          return (
            <ion-item class={'theme-item'}>
              <div class='info' style={{ backgroundColor: item.color }}></div>
              <div class='name'>{(this as any).$tl(item.lanResTag, item.title)}</div>
              <ion-button
                class={{ select: true, use: isUse }}
                slot='end'
                style={[isUse ? { borderColor: item.color } : {}]}
                onClick={(event: any) => {
                  this.changeInternalTheme(item, event);
                }}
              >
                {isUse ? (this as any).$tl('theme.inuse', '使用中') : (this as any).$tl('theme.use', '使用')}
              </ion-button>
            </ion-item>
          );
        }),
        <ion-item
          class={{ 'theme-item': true, 'theme-item--custom': true }}
          onClick={(event: any) => {
            this.handleCustom(event);
          }}
        >
          <div class='info'></div>
          <div class='name'>{(this as any).$tl('theme.custom', '自定义')}</div>
          <ion-button
            slot='end'
            class={{ select: true, use: this.activeTheme.isCustom }}
            onClick={(event: any) => {
              event.stopPropagation();
              if (this.showCustomPanel) this.applyCustomTheme(event);
            }}
          >
            {this.activeTheme.isCustom
              ? (this as any).$tl('theme.inuse', '使用中')
              : (this as any).$tl('theme.use', '使用')}
          </ion-button>
        </ion-item>,
      ];
    },

    /**
     * @description 渲染自定义面板
     * @return {*}
     */
    renderCustomPanel() {
      if (this.showCustomPanel) {
        return (
          <div class='theme-content--custom'>
            <div class='theme-content__toolbar'>
              <ion-buttons>
                <ion-button
                  onClick={(event: any) => {
                    this.resetAppTheme();
                  }}
                >
                  {(this as any).$tl('theme.reset', '重置')}
                </ion-button>
                <ion-button>{(this as any).$tl('theme.share', '分享')}</ion-button>
              </ion-buttons>
            </div>
            <ion-list class='theme-content__options'>
              {this.themeOptions.map((option: IParam) => {
                return this.renderGroups(option);
              })}
            </ion-list>
          </div>
        );
      }
    },
  },

  /**
   * @description 渲染主题组件
   * @return {*}
   */
  render() {
    return [this.renderContent(), this.renderCustomPanel()];
  },
});
